package tester.component;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Comparator {
    public static final String prefix = "CheckPoint";
    /**
     * 比较两个文件内容是否完全相同
     * @param file1 第一个文件路径
     * @param file2 第二个文件路径
     * @return 相同返回true，不同返回false
     * @throws IOException 如果文件读取失败
     */
    public static boolean compareFiles(String file1, String file2) throws IOException {
        // 基本校验
        if (file1 == null || file2 == null) {
            throw new IllegalArgumentException("文件路径不能为null");
        }

        Path path1 = Paths.get(file1);
        Path path2 = Paths.get(file2);

        // 快速检查文件大小是否相同
        if (Files.size(path1) != Files.size(path2)) {
            return false;
        }

        // 逐行比较内容
        try (BufferedReader reader1 = Files.newBufferedReader(path1);
             BufferedReader reader2 = Files.newBufferedReader(path2)) {

            String line1, line2;
            while ((line1 = reader1.readLine()) != null) {
                line2 = reader2.readLine();
                if (!Objects.equals(line1, line2)) {
                    return false;
                }
            }
            // 检查file2是否还有剩余行
            return reader2.readLine() == null;
        }
    }

    public static void compare(String file1, String file2) {
        try {
            compareFiles(Saver.getFilePath(file1), Saver.getFilePath(file2));
            generateDiffReport(Saver.getFilePath(file1), Saver.getFilePath(file2),
                    Saver.getFilePath("diff_report"));
            System.out.println("差异报告已生成: " + Saver.getFilePath("diff_report"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 比较两个文件并返回差异报告
     * @param file1 第一个文件路径
     * @param file2 第二个文件路径
     * @return 差异报告字符串，包含所有不同的行
     * @throws IOException 如果文件读取失败
     */
    public static String getFileDiff(String file1, String file2) throws IOException {
        List<String> lines1 = readAllLines(file1);
        List<String> lines2 = readAllLines(file2);

        StringBuilder diff = new StringBuilder();
        diff.append(prefix).append(": 文件比较报告\n");
        diff.append("文件1: ").append(file1).append("\n");
        diff.append("文件2: ").append(file2).append("\n\n");

        int maxLines = Math.max(lines1.size(), lines2.size());
        boolean hasDiff = false;

        for (int i = 0; i < maxLines; i++) {
            String line1 = i < lines1.size() ? lines1.get(i) : "<文件结束>";
            String line2 = i < lines2.size() ? lines2.get(i) : "<文件结束>";

            if (!line1.equals(line2)) {
                diff.append(String.format("行 %d:\n", i + 1));
                diff.append(String.format("< %s\n", line1));
                diff.append(String.format("> %s\n\n", line2));
                hasDiff = true;
            }
        }

        if (!hasDiff) {
            diff.append("两个文件内容完全相同\n");
        }

        return diff.toString();
    }

    /**
     * 将比较结果写入报告文件
     * @param file1 第一个文件路径
     * @param file2 第二个文件路径
     * @param outputFile 输出报告文件路径
     * @throws IOException 如果文件操作失败
     */
    public static void generateDiffReport(String file1, String file2, String outputFile) throws IOException {
        String report = getFileDiff(file1, file2);
        Files.write(Paths.get(outputFile), report.getBytes(), StandardOpenOption.CREATE);
    }
    /**
     * 读取文件所有行
     * @param filePath 文件路径
     * @return 包含所有行的列表
     * @throws IOException 如果文件读取失败
     */
    private static List<String> readAllLines(String filePath) throws IOException {
        try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
            return lines.collect(Collectors.toList());
        }
    }

}
